package org.etcsoft.examples.jpa.config;

import java.util.Properties;

import javax.sql.DataSource;

import org.etcsoft.examples.jpa.repository.support.DefaultRepositoryFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.hibernate4.HibernateExceptionTranslator;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

/**
 * @author korman21@gmail.com
 */
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        basePackages = {"kr.wisestone.owl.repository"}
      , entityManagerFactoryRef = "entityManagerFactory"
      , transactionManagerRef = "transactionManager"
      , repositoryFactoryBeanClass = DefaultRepositoryFactoryBean.class
)
@ComponentScan (
        basePackages = {
                "org.etcsoft.examples.jpa.config"
              , "org.etcsoft.examples.jpa.domain"
              , "org.etcsoft.examples.jpa.service"
              , "org.etcsoft.examples.jpa.repository"
        }
      , excludeFilters=@ComponentScan.Filter(Controller.class)
)
public class RootContextConfiguration {
    @Bean
    public DataSource dataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost/test");
        dataSource.setUsername("root");
        dataSource.setPassword("1111");

        Properties connectionProperties = new Properties();
        connectionProperties.put("zeroDateTimeBehavior", "convertToNull");
        dataSource.setConnectionProperties(connectionProperties );

        return dataSource;
    }

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
        LocalContainerEntityManagerFactoryBean factory =
                new LocalContainerEntityManagerFactoryBean();

        factory.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
        factory.setDataSource(this.dataSource());

        return factory;
    }

    @Bean
    public PlatformTransactionManager transactionManager() {
        JpaTransactionManager txManager = new JpaTransactionManager();
        txManager.setEntityManagerFactory(this.entityManagerFactory().getObject());
        return txManager;
    }

    @Bean
    public HibernateExceptionTranslator hibernateExceptionTranslator() {
        return new HibernateExceptionTranslator();
    }

    @Bean
    public ReloadableResourceBundleMessageSource messageSource() {
        ReloadableResourceBundleMessageSource source = new ReloadableResourceBundleMessageSource();

        source.setDefaultEncoding("UTF-8");
        source.setBasename("classpath:messages");
        source.setUseCodeAsDefaultMessage(true);
        return source;
    }

    @Bean
    public MessageSourceAccessor messageSourceAccessor(ReloadableResourceBundleMessageSource source){
        MessageSourceAccessor msa = new MessageSourceAccessor(source);
        return msa;
    }
}
